package com.ouc.common.utils;


import org.apache.commons.math3.stat.regression.SimpleRegression;

import java.math.BigDecimal;
import java.util.*;

public final class MathUtils {

    private MathUtils() {
    }

    public static int middle(int a, int b, int c) {
        return a > b ? (b > c ? b : (a > c ? c : a)) : (a > c ? a : (b > c ? c : b));
    }

    public static long middle(long a, long b, int c) {
        return a > b ? (b > c ? b : (a > c ? c : a)) : (a > c ? a : (b > c ? c : b));
    }

    public static float middle(float a, float b, float c) {
        return a > b ? (b > c ? b : (a > c ? c : a)) : (a > c ? a : (b > c ? c : b));
    }

    public static double middle(double a, double b, double c) {
        return a > b ? (b > c ? b : (a > c ? c : a)) : (a > c ? a : (b > c ? c : b));
    }

    public static boolean isMiddle(int left, int right, int target) {
        return (left - target) * (right - target) <= 0;
    }

    public static boolean isMiddle(long left, long right, int target) {
        return (left - target) * (right - target) <= 0;
    }

    public static boolean isMiddle(float left, float right, float target) {
        return (left - target) * (right - target) <= 0;
    }

    public static boolean isMiddle(double left, double right, double target) {
        return (left - target) * (right - target) <= 0;
    }

    /**
     * 判断是否待测值在给定的值范围中间
     *
     * @param test  测试值
     * @param start 给定开始值
     * @param end   给定结束值
     * @return
     */
    public static boolean between(int test, int start, int end) {
        return test >= start && test <= end;
    }

    public static boolean between(long test, long start, long end) {
        return test >= start && test <= end;
    }

    public static boolean between(float test, float start, float end) {
        return test >= start && test <= end;
    }

    public static boolean between(double test, double start, double end) {
        return test >= start && test <= end;
    }

    /**
     * 多个数求平均数
     *
     * @param arr
     * @return
     */
    public static int avg(int... arr) {
        int sum = 0;
        for (int i : arr) {
            sum += i;
        }
        return sum / arr.length;
    }

    /**
     * 多个数求平均数
     *
     * @param arr
     * @return
     */
    public static double avg(double... arr) {
        int sum = 0;
        for (double i : arr) {
            sum += i;
        }
        return sum / arr.length;
    }

    /**
     * 转化为弧度(rad)
     */
    public static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    /**
     * 判断两个数是否符号相反。其中，0 为正数
     *
     * @param x
     * @param y
     * @return
     */
    public static boolean isOppositeSign(int x, int y) {
        return (x ^ y) < 0;
    }

    /**
     * 判断两个数是否符号相反。其中，0 为正数
     *
     * @param x
     * @param y
     * @return
     */
    public static boolean isOppositeSign(float x, float y) {
        if ((Math.abs(x) == x && Math.abs(y) == y) || (Math.abs(x) != x && Math.abs(y) != y)) {
            return false;
        }
        return true;
    }

    /**
     * 获取 int 一维数组的最大值
     *
     * @param arr int 一维数组
     * @return
     */
    public static int max(int[] arr) {
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(arr[i], max);
        }
        return max;
    }

    /**
     * 获取 float 一维数组的最大值
     *
     * @param arr float 一维数组
     * @return
     */
    public static float max(float[] arr) {
        float max = Float.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            if (!Float.isNaN(arr[i])) {
                max = Math.max(max, arr[i]);
            }
        }
        return max;
    }

    /**
     * 获取 int 一维数组的最小值
     *
     * @param arr int 一维数组
     * @return
     */
    public static int min(int[] arr) {
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < arr.length; i++) {
            min = Math.min(arr[i], min);
        }
        return min;
    }

    /**
     * 获取 float 一维数组的最小值
     *
     * @param arr float 一维数组
     * @return
     */
    public static float min(float[] arr) {
        float min = Float.MAX_VALUE;
        for (int i = 0; i < arr.length; i++) {
            if (!Float.isNaN(arr[i])) {
                min = Math.min(min, arr[i]);
            }
        }
        return min;
    }

    /**
     * 获取 int 二维数组的最小值
     *
     * @param arr int 二维数组
     * @return
     */
    public static int min(int[][] arr) {
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < arr.length; i++) {
            min = Math.min(min, min(arr[i]));
        }
        return min;
    }

    /**
     * 获取 float 二维数组的最小值
     *
     * @param arr float 二维数组
     * @return
     */
    public static float min(float[][] arr) {
        float min = Float.MAX_VALUE;
        for (int i = 0; i < arr.length; i++) {
            min = Math.min(min, min(arr[i]));
        }
        return min;
    }

    /**
     * 获取数组最小值和最大值
     *
     * @param arr 数组
     * @return [min, max]
     */
    public static float[] minAndMax(float[] arr) {
        float min = Float.MAX_VALUE;
        float max = Float.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            if (!Float.isNaN(arr[i])) {
                min = Math.min(min, arr[i]);
                max = Math.max(max, arr[i]);
            }
        }
        return new float[]{min, max};
    }

    /**
     * 获取数组最小值和最大值
     *
     * @param arr 数组
     * @return [min, max]
     */
    public static float[] minAndMax(float[][] arr) {
        float min = Float.MAX_VALUE;
        float max = Float.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                if (!Float.isNaN(arr[i][j])) {
                    min = Math.min(min, arr[i][j]);
                    max = Math.max(max, arr[i][j]);
                }
            }
        }
        return new float[]{min, max};
    }

    /**
     * 获取list集合的最小值和最大值
     *
     * @param list
     * @return
     */
    public static Float[] minAndMax(List<Float> list) {
        float min = Float.MAX_VALUE;
        float max = Float.MIN_VALUE;
        for (int i = 0; i < list.size(); i++) {
            if (!Float.isNaN(list.get(i))) {
                min = Math.min(min, list.get(i));
                max = Math.max(max, list.get(i));
            }
        }
        return new Float[]{min, max};

    }

    /**
     * 获取 p1,p2 两点斜率 k
     * 返回斜率 k
     * a=(y2-y1)/(x2-x1);
     *
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @param scale 保留小数位数
     * @return 返回斜率 k
     */
    public static float getLineSlope(float x1, float y1, float x2, float y2, int scale) {
        return BigDecimal.valueOf((y2 - y1) / (x2 - x1))
                .setScale(scale, BigDecimal.ROUND_HALF_UP)
                .floatValue();
    }


    /**
     * 二维数组归一化
     * 使用最简单的线性归一化X = (x-Min)/(Max-Min)
     * 通过设置的最大值最小值确定最大值最小值
     *
     * @param originData 初始数组
     * @param fixedMin   设置的最大值
     * @param fixedMax   设置的最小值
     * @param flag       是否是自动找最大值最小值
     * @return
     */
    public static float[][] normalizeByLinear(float[][] originData, float fixedMin, float fixedMax, boolean flag) {
        float[][] result = new float[originData.length][originData[0].length];
        if (flag) {
            for (int i = 0; i < originData.length; i++) {
                for (int j = 0; j < originData[i].length; j++) {
                    result[i][j] = (originData[i][j] - fixedMin) / (fixedMax - fixedMin);
                }
            }
            return result;
        }
        for (int i = 0; i < originData.length; i++) {
            for (int j = 0; j < originData[i].length; j++) {
                /**
                 * 如果比设定的最大值或最小值大或小
                 * 则分别设置这个值为1或0
                 */
                if (originData[i][j] > fixedMax) {
                    result[i][j] = 1;
                } else if (originData[i][j] < fixedMin) {
                    result[i][j] = 0;
                } else {
                    result[i][j] = (originData[i][j] - fixedMin) / (fixedMax - fixedMin);
                }

            }
        }
        return result;
    }


    /**
     * 归一化方法重载，用于自动找最大值最小值
     * 使用最简单的线性归一化X = (x-Min)/(Max-Min)
     *
     * @param originData 二维数组
     * @return
     */
    public static float[][] normalizeByLinear(float[][] originData) {
        float min = Integer.MAX_VALUE;
        float max = Integer.MIN_VALUE;
        for (float[] originDatum : originData) {
            for (float v : originDatum) {
                if (!Float.isNaN(v)) {
                    if (v < min) {
                        min = v;
                    }
                    if (v > max) {
                        max = v;
                    }
                }
            }
        }
        return normalizeByLinear(originData, min, max, true);
    }

    /**
     * 二维数组归一化
     * 使用最简单的线性归一化X = (x-Min)/(Max-Min)
     *
     * @param originData 原始数据
     * @return
     */
    public static float[][] normalizeByStandard(float[][] originData) {
        float min = 0;
        float max = 1;
        float sum = 0;
        float num = 0;
        float[][] normalizeData = originData;

        for (float[] originDatum : originData) {
            for (float v : originDatum) {
                sum += v;
                num++;
            }
        }
        float average = new BigDecimal(sum).divide(new BigDecimal(num), 4).floatValue();
        float variance = 0;
        for (float[] originDatum : originData) {
            for (float v : originDatum) {
                variance += Math.pow((v - average), 2);
            }
        }
        //  获取到标准差
        variance = (float) Math.sqrt(new BigDecimal(variance).divide(new BigDecimal(num), 4).doubleValue());
        for (int i = 0; i < originData.length; i++) {
            for (int j = 0; j < originData[i].length; j++) {
                if (Float.isNaN(originData[i][j])) {
                    normalizeData[i][j] = Float.NaN;
                }
                normalizeData[i][j] = new BigDecimal(originData[i][j] - average).divide(new BigDecimal(variance), 4).floatValue();
            }
        }
        return normalizeData;
    }

    /**
     * 两个数相减
     * 总是大数减去小数
     *
     * @param a 第一个数
     * @param b 第二个数
     * @return 差值
     */
    public static float subtractOfAbs(float a, float b) {
        return a > b ? BigDecimal.valueOf(a).subtract(BigDecimal.valueOf(b)).floatValue() : BigDecimal.valueOf(b).subtract(BigDecimal.valueOf(a)).floatValue();
    }

    public static float[] getLineFromData2D(float[][] data, float degree, boolean radianFlag) {

        int yLength = data.length;
        int xLength = data[0].length;
        int centerX = xLength / 2;
        int centerY = yLength / 2;

        float k = (float) (radianFlag ? Math.tan(degree) : Math.tan(Math.toRadians(degree)));
        boolean flag = false;
        if ((float) Math.tan(Math.toRadians(90)) == k) {
            flag = true;
        }

        float[] line = new float[xLength];
        if (!flag) {
            float b = centerY - k * centerX;
            for (int i = 0; i < xLength; i++) {
                int j = yLength - 1 - (int) (b + i * k);
                if (j >= yLength) {
                    j = yLength - 1;
                } else if (j < 0) {
                    j = 0;
                }
                line[i] = data[j][i];
            }
        } else {
            for (int i = 0; i < yLength; i++) {
                line[i] = data[i][centerX];
            }
        }
        return line;
    }

    public static byte[] int2Byte(int x) {
        byte[] arr = new byte[4];
        arr[0] = (byte) (x & 0xff); //最低位
        arr[1] = (byte) ((x >> 8) & 0xff);  //次低位
        arr[2] = (byte) ((x >> 16) & 0xff); //次高位
        arr[3] = (byte) (x >> 24);  //最高位，无符号右移
        return arr;
    }

    public static int byte2Int(byte[] arr) {
        return (arr[0] & 0xff) | ((arr[1] << 8) & 0xff00) | ((arr[2] << 24) >>> 8) | (arr[3] << 24);
    }

    public static float bytes2Float(byte[] arr) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            value |= ((arr[i] & 0xff)) << (8 * i);
        }
        return Float.intBitsToFloat(value);
    }

    public static double bytes2Double(byte[] arr) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value |= ((long) (arr[i] & 0xff)) << (8 * i);
        }
        return Double.longBitsToDouble(value);
    }

    // population variance 总体方差
    public static double POP_Variance(double[] data) {
        double mean = avg(data);
        double variance = 0;
        for (double datum : data) {
            variance = variance + (Math.pow((datum - mean), 2));
        }
        variance = variance / data.length;
        return variance;
    }

    // population standard deviation 总体标准差
    public static double POP_STD_dev(double[] data) {
        return Math.sqrt(POP_Variance(data));
    }

    //sample variance 样本方差
    public static double Sample_Variance(double[] data) {
        double mean = avg(data);
        double variance = 0;
        for (double datum : data) {
            variance = variance + (Math.pow((datum - mean), 2));
        }
        variance = variance / (data.length - 1);
        return variance;
    }

    // sample standard deviation 样本标准差
    public static double Sample_STD_dev(double[] data) {
        return Math.sqrt(Sample_Variance(data));
    }


    /**
     * 数据四舍五入
     *
     * @param v     原始数据
     * @param scale 保留小数位数
     * @return
     */
    public static float round(float v, int scale) {
        return (float) (Math.round(v * Math.pow(10, scale)) / Math.pow(10, scale));
    }

    /**
     * 数据四舍五入
     *
     * @param v     原始数据
     * @param scale 保留小数位数
     * @return
     */
    public static double round(double v, int scale) {
        return (Math.round(v * Math.pow(10, scale)) / Math.pow(10, scale));
    }

    /**
     * 线性插值
     *
     * @param x0     第一个x值
     * @param x1     第二个x值（终点值）
     * @param y0     第一个y值
     * @param y1     第二个y值
     * @param valueX 想要计算的y值对应的x值
     * @return
     */
    public static float interpolation(float x0, float x1, float y0, float y1, float valueX) {
        float k = (y1 - y0) / (x1 - x0);
        return y0 + (valueX - x0) * k;
    }

    /**
     * 一维数组内插
     *
     * @param arrList  集合
     * @param interval 间隔，大于这个间隔才会进行插值
     * @return
     */
    public static List<Float> interpolation(List<Float> arrList, float interval) {
        List<Float> floats = new ArrayList<>();
        for (int i = 0; i < arrList.size() - 1; i++) {
            if (Math.abs(arrList.get(i + 1) - arrList.get(i)) > interval) {
                for (int j = 0; j <= (int) (Math.abs((arrList.get(i + 1) - arrList.get(i)) / interval)); j++) {
                    if ((arrList.get(i + 1) - arrList.get(i)) < 0) {
                        if ((arrList.get(i) - j * interval) == arrList.get(i + 1)) {
                            continue;
                        }
                        floats.add(arrList.get(i) - j * interval);
                    } else {
                        if ((arrList.get(i) + j * interval) == arrList.get(i + 1)) {
                            continue;
                        }
                        floats.add(arrList.get(i) + j * interval);
                    }
                }

            } else {
                floats.add(arrList.get(i));
            }
        }
        floats.add(arrList.get(arrList.size() - 1));
        return floats;

    }

    /**
     * 获取两个数组计算得到的k斜率
     * 一个y对应一个x，长度至少应为2
     *
     * @param yArr y值的对应数组
     * @param xArr x值的对应数组
     * @return
     */
    public static float[] getKOfLine(float[] yArr, float[] xArr) {
        float[] result = new float[yArr.length - 1];
        for (int i = 0; i < yArr.length - 1; i++) {
            result[i] = (yArr[i + 1] - yArr[i]) / (xArr[i + 1] - xArr[i]);
        }
        return result;
    }

    /**
     * 获取两个数组计算得到的k斜率
     * 一个y对应一个x，长度至少应为2
     *
     * @param yArr y值的对应集合
     * @param xArr x值的对应集合
     * @return
     */
    public static List<Float> getKOfLine(List<Float> yArr, List<Float> xArr) {
        List<Float> resultList = new ArrayList<>();
        for (int i = 0; i < yArr.size() - 1; i++) {
            resultList.add((yArr.get(i + 1) - yArr.get(i)) / (xArr.get(i + 1) - xArr.get(i)));
        }
        return resultList;
    }

    /**
     * 获取某个值在对应曲线中的y
     * 使用线性插值方法
     *
     * @param x  x数组
     * @param y  y数组
     * @param x0 需要求的值
     * @return
     */
    public static float linearInterpolation(float[] x, float[] y, float x0) {
        int n = x.length;
        /*搜索值不是数组元素，且在数组范围内，从1开始计数，得 - 插入点索引值
         * 搜索值是数组元素，从0开始计数，得搜索值的索引值
         * 搜索值不是数组元素，且大于数组内元素，索引值为 – (length + 1),所以-i-1就是length+1-1=length
         * 搜索值不是数组元素，且小于数组内元素，索引值为 – 1所以-i-1就是1-1=0*/
        int i = Arrays.binarySearch(x, x0);
        if (i < 0) {
            i = -i - 1;
            if (i == 0 || i == n) {
                return Float.NaN;
            }
            float x1 = x[i - 1];
            float x2 = x[i];
            float y1 = y[i - 1];
            float y2 = y[i];
            return y1 + (x0 - x1) * (y2 - y1) / (x2 - x1);
        } else {
            return y[i];
        }
    }


    /**
     * 获取集合中的最大值和最小值
     * 并返回map集合，
     * key为最大值最小值，和最大值最小值的索引
     *
     * @param list 集合
     * @return
     */
    public static Map<String, Float> getMinAndMax(List<Float> list) {
        Map<String, Float> map = new HashMap<>();
        float max = Integer.MIN_VALUE;
        float min = Integer.MAX_VALUE;
        int maxIndex = 0;
        int minIndex = 0;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) > max) {
                max = list.get(i);
                maxIndex = i;
            }
            if (list.get(i) < min) {
                min = list.get(i);
                minIndex = i;
            }
        }
        map.put("minValue", min);
        map.put("maxValue", max);
        map.put("maxIndex", (float) maxIndex);
        map.put("minIndex", (float) minIndex);
        return map;
    }

    public static Map<String, Float> getMinAndMax(float[] data) {
        Map<String, Float> map = new HashMap<>();
        float max = Integer.MIN_VALUE;
        float min = Integer.MAX_VALUE;
        int maxIndex = 0;
        int minIndex = 0;
        for (int i = 0; i < data.length; i++) {
            if (data[i] > max) {
                max = data[i];
                maxIndex = i;
            }
            if (data[i] < min) {
                min = data[i];
                minIndex = i;
            }
        }
        map.put("minValue", min);
        map.put("maxValue", max);
        map.put("maxIndex", (float) maxIndex);
        map.put("minIndex", (float) minIndex);
        return map;
    }

    public static Map<String, Float> getMinAndMax(double[] data) {
        Map<String, Float> map = new HashMap<>();
        double max = Integer.MIN_VALUE;
        double min = Integer.MAX_VALUE;
        int maxIndex = 0;
        int minIndex = 0;
        for (int i = 0; i < data.length; i++) {
            if (data[i] > max) {
                max = data[i];
                maxIndex = i;
            }
            if (data[i] < min) {
                min = data[i];
                minIndex = i;
            }
        }
        map.put("minValue", (float) min);
        map.put("maxValue", (float) max);
        map.put("maxIndex", (float) maxIndex);
        map.put("minIndex", (float) minIndex);
        return map;
    }

    /**
     * 使用滑动窗口进行滤波
     *
     * @param data
     * @param windowSize
     * @return
     */
    public static double[] smoothData(float[] data, int windowSize) {
        double[] smoothedData = new double[data.length];
        for (int i = 0; i < data.length; i++) {
            double sum = 0;
            int count = 0;
            for (int j = Math.max(0, i - windowSize + 1); j <= Math.min(i, data.length - 1); j++) {
                sum += data[j];
                count++;
            }
            smoothedData[i] = sum / count;
        }
        return smoothedData;
    }

    /**
     * 使用滑动窗口进行滤波
     *
     * @param data
     * @param windowSize
     * @return
     */
    public static double[] smoothData(double[] data, int windowSize) {
        double[] smoothedData = new double[data.length];
        for (int i = 0; i < data.length; i++) {
            double sum = 0;
            int count = 0;
            for (int j = Math.max(0, i - windowSize + 1); j <= Math.min(i, data.length - 1); j++) {
                sum += data[j];
                count++;
            }
            smoothedData[i] = sum / count;
        }
        return smoothedData;
    }

    /**
     * 获取数组中超过某个值的一段数组
     * 如果没有返回-1
     *
     * @param array  目标数组
     * @param target 目标值
     * @return 开始索引和结束索引
     */
    public static int[] findSubArray(float[] array, float target) {
        int startIndex = -1;
        int endIndex = -1;
        for (int i = 0; i < array.length - 1; i++) {
            //  寻找第一个上一个值大于target，下一个值小于target的索引
            if ((array[i] - target) * (array[i + 1] - target) <= 0 && startIndex == -1) {
                startIndex = i;
            } else if ((array[i] - target) * (array[i + 1] - target) <= 0 && startIndex != -1) {
                endIndex = i - 1;
                break;
            }
        }
        return new int[]{startIndex, endIndex};
    }

    /**
     * 获取数组中超过某个值的一段数组
     * 如果没有返回-1
     *
     * @param array  目标数组
     * @param target 目标值
     * @return 开始索引和结束索引
     */
    public static int[] findSubArray(double[] array, float target) {
        int startIndex = -1;
        int endIndex = -1;
        for (int i = 0; i < array.length - 1; i++) {
            //  寻找第一个上一个值大于target，下一个值小于target的索引
            if ((array[i] - target) * (array[i + 1] - target) <= 0 && startIndex == -1) {
                startIndex = i;
            } else if ((array[i] - target) * (array[i + 1] - target) <= 0 && startIndex != -1) {
                endIndex = i - 1;
                break;
            }
        }
        return new int[]{startIndex, endIndex};
    }

    /**
     * 获取所有包含target的索引
     *
     * @param array  目标数组
     * @param target 目标值
     * @return
     */
    public static List<Integer> findAllSubArray(double[] array, float target) {
        List<Integer> resList = new ArrayList<>();
        for (int i = 0; i < array.length - 1; i++) {
            if (isMiddle(array[i], array[i + 1], target)) {
                resList.add(i);
            }
        }
        return resList;
    }

    /**
     * 对数组进行取绝对值操作
     *
     * @param arr 原始数组
     * @return
     */
    public static double[] absArr(double[] arr) {
        double[] result = new double[arr.length];
        for (int i = 0; i < arr.length; i++) {
            result[i] = Math.abs(arr[i]);
        }
        return result;
    }

    /**
     * 对数组进行取绝对值操作
     *
     * @param arr 原始数组
     * @return
     */
    public static float[] absArr(float[] arr) {
        float[] result = new float[arr.length];
        for (int i = 0; i < arr.length; i++) {
            result[i] = Math.abs(arr[i]);
        }
        return result;
    }

    /**
     * 一维数组寻找卡住target值的索引
     *
     * @param array  原始一维数组
     * @param target 目标值
     * @return
     */
    public static int getArrayIndex(float[] array, float target) {
        int index = -1;

        if (array.length < 2) {
            return index;
        }
        for (int i = 0; i < array.length - 1; i++) {
            //  寻找第一个上一个值大于target，下一个值小于target的索引
            if ((array[i] - target) * (array[i + 1] - target) <= 0) {
                index = i;
                break;
            }

        }
        return index;
    }

    /**
     * 一维数组寻找卡住target值的索引
     *
     * @param array  原始一维数组
     * @param target 目标值
     * @return
     */
    public static int getArrayIndex(double[] array, float target) {
        int index = -1;

        if (array.length < 2) {
            return index;
        }
        for (int i = 0; i < array.length - 1; i++) {
            //  寻找第一个上一个值大于target，下一个值小于target的索引
            if ((array[i] - target) * (array[i + 1] - target) <= 0) {
                index = i;
                break;
            }

        }
        return index;
    }

    public static float[] createNaNArray(int n) {
        float[] array = new float[n];
        for (int i = 0; i < n; i++) {
            array[i] = Float.NaN;
        }
        return array;
    }

    /**
     * 使用最小二乘法拟合直线
     * 获取直线的斜率和截距
     * 使用的公式是y=kx+b
     * 也就是kx-y+b=0；
     *
     * @param x x坐标
     * @param y y坐标
     * @return 一个长度为2的一维数组，第一个值是斜率，第二个值是截距
     */
    public static double[] leastSquare(double[] x, double[] y) {
        double[] result = new double[2];
        SimpleRegression regression = new SimpleRegression();
        for (int i = 0; i < x.length; i++) {
            regression.addData(x[i], y[i]);
        }
        //  获取直线的斜率
        result[0] = regression.getSlope();
        result[1] = regression.getIntercept();
        return result;
    }

    /**
     * 一维线性插值值
     * x，插值点
     * x1，x2，v1，v2已知点
     */
    public static float linearInterpolation(float x1, float x2, float x, float v1, float v2) {
        return (v1 * (x2 - x) + v2 * (x - x1)) / (x2 - x1);
    }

    /**
     * 二维线性插值
     * 左上 x1,y1
     * 右下 x2，y2
     * v1 v2
     * v3 v4
     */
    public static float bilinearInterpolation(float x1, float x2, float y1, float y2, float x, float y, float v1, float v2, float v3, float v4) {
        float t1 = (v1 * (x2 - x) + v2 * (x - x1)) / (x2 - x1);
        float t2 = (v3 * (x2 - x) + v4 * (x - x1)) / (x2 - x1);
        return (t1 * (y2 - y) + t2 * (y - y1)) / (y2 - y1);
    }

    /**
     * 获取数组中某个点的值（最临近方法）
     * @param valveArr
     * @param xArr
     * @param yArr
     * @param x
     * @param y
     * @return
     */
    public static Float getPointFromArr(float[][] valveArr, float[] xArr, float[] yArr, float x, float y) {
        if (x < xArr[0] || x > xArr[xArr.length-1] || y < yArr[0] || y > yArr[yArr.length-1])
            return Float.NaN;
        else {
            int l = 0, r = xArr.length-1, i = 0, j = 0;
            while (l + 1 < r) {
                int mid = (l + r) >> 1;
                if (xArr[mid] > x) r = mid;
                else l = mid;
            }
            i = (x - xArr[l]) < (xArr[r] - x) ? l : r;
            l = 0;
            r = yArr.length-1;
            while (l + 1 < r) {
                int mid = (l + r) >> 1;
                if (yArr[mid] > y) r = mid;
                else l = mid;
            }
            j= (y-yArr[l])<(yArr[r]-y)?l:r;
            return valveArr[i][j];
        }
    }
}

